package singleton;

/**
 * @ProjectName: interview
 * @Package: singleton
 * @ClassName: Singleton01
 * @Author: chenmengqi
 * @Description: null
 * @Date: 2020/2/13 8:44 下午
 * @Version: 1.0
 */
public class SingletonTest01 {
    public static void main(String[] args) {
        Singleton01 instance1 = Singleton01.getInstance();
        Singleton01 instance2 = Singleton01.getInstance();
        System.out.println(instance1 == instance2);
        System.out.println(instance1.equals(instance2));
    }
}


/**
 * 饿汉式
 */
class Singleton01 {
    private Singleton01() {
    }

    private final static Singleton01 instance = new Singleton01();

    public static Singleton01 getInstance() {
        return instance;
    }
}



/**
 * 懒汉式
 */
class Singleton03 {
    private Singleton03() {
    }

    private static Singleton03 instance;


    public static Singleton03 getInstance() {
        if (instance == null) {
            instance = new Singleton03();
        }
        return instance;
    }
}

// 懒汉式(线程安全，同步方法,效率慢)
class Singleton04 {
    private static Singleton04 instance;

    private Singleton04() {
    }

    //提供一个静态的公有方法，加入同步处理的代码，解决线程安全问题
    //即懒汉式
    public static synchronized Singleton04 getInstance() {
        if (instance == null) {
            instance = new Singleton04();
        }
        return instance;
    }
}

// 懒汉式(线程安全，同步方法,效率高)
class Singleton05 {
    private static volatile Singleton05 instance;

    private Singleton05() {}

    //提供一个静态的公有方法，加入双重检查代码，解决线程安全问题, 同时解决懒加载问题
    //同时保证了效率, 推荐使用

    public static Singleton05 getInstance() {
        if(instance == null) {
            synchronized (Singleton05.class) {
                if(instance == null) {
                    instance = new Singleton05();
                }
            }

        }
        return instance;
    }
}



// 静态内部类完成， 推荐使用
class Singleton06 {
    private static volatile Singleton instance;

    //构造器私有化
    private Singleton06() {}

    //写一个静态内部类,该类中有一个静态属性 Singleton
    private static class SingletonInstance {
        private static final Singleton06 INSTANCE = new Singleton06();
    }

    //提供一个静态的公有方法，直接返回SingletonInstance.INSTANCE

    public static synchronized Singleton06 getInstance() {

        return SingletonInstance.INSTANCE;
    }
}

//使用枚举，可以实现单例, 推荐
enum Singleton {
    INSTANCE; //属性
    public void sayOK() {
        System.out.println("ok~");
    }
}
